# -*- coding:utf-8 -*-
"""
@Time : 2020-12-15 11:54
@Author: langengel
@Des: 服务商登录
"""

import json
from Authorization.auth import create_access_token
from application.service.common import check_user_for_service
from config.config import REG_EXPIRE
from config.security import ACCESS_TOKEN_EXPIRE_MINUTES
from models.saas import User, Wechat
from saas.response.BaseResponse import success, fail
from saas.utils.utils import get_times, check_password, req_code
from validator.service import ServiceLogin
from fastapi import Request

from validator.user import AccountLogin


async def out_login():

    return success(msg="已退出登陆")


async def service_login(req: Request, data: ServiceLogin):
    """
    服务商用户登录
    :param req:
    :param data:
    :return:
    """
    services_data = await req.app.state.cache.get(data.web_code + '-myService')
    if not services_data:
        return fail(code=2001, msg="页面超时！")
    # 解码用户服务商信息
    services = json.loads(services_data)

    # 判断请求的真实性
    for service in services:
        # 如果当前选择登陆的用户与服务商id不相符 表现为不正确
        if service["u_id"] == data.u_id and service["s_id"] != data.s_id:
            return fail(msg="未获得服务商的许可")

    # 查询选择的目标服务商和用户真实性
    user = await check_user_for_service(s_id=data.s_id, u_id=data.u_id)
    if not user:
        return fail(msg="未获得服务商的许可")

    # 服务商是否到期
    if get_times() > round(user.service.expire_time.timestamp()*1000):
        return fail(msg="服务商账户已到期")

    # 用户是否激活
    if user.u_status == 0:
        return fail(msg="管理员账户未激活")

    # 用户是否禁用
    if user.u_status != 1:
        return fail(msg="账户已停用")

    # 封装jwt data

    token_data = {
        "user": user.pk,
        "is_admin": user.type,
        "service": user.service.pk
    }

    # 更新访问IP
    await User().filter(pk=user.pk).update(client_host=req.client.host)

    # 生成jwt token
    access_token = create_access_token(data=token_data)

    await req.app.state.cache.delete(data.web_code + '-myService')

    return success(
        data={
            "access_token": access_token,
            "expires_in": ACCESS_TOKEN_EXPIRE_MINUTES * 60,
            "token_type": "bearer",
        },
        msg="登录成功"

    )


async def account_check(req: Request, login: AccountLogin):
    """
    # 账户查询服务商 用于账号登陆
    :param req:
    :param login:
    :return:
    """
    # 用户查询
    users = await User().filter(u_phone=login.username)
    if not users:
        return fail(msg="登陆失败,用户名或密码错误")

    check_pass_user = []
    # 密码判断
    for user in users:
        if user.password and check_password(login.password, user.password):
            check_pass_user.append(user)

    if not check_pass_user:
        return fail(msg="验证失败,用户名或密码错误")

    # 获取用户的服务商
    service_list = await user_to_service(check_pass_user)
    # 获取请求码
    code = req_code()

    # 缓存服务商列表
    await req.app.state.cache.set(code + '-myService', json.dumps(service_list), expire=REG_EXPIRE)

    return success(data={"web_code": code}, msg="验证通过")


async def wechat_to_user(openid: str):
    """
    openid获取服务商
    :param openid: 用户微信open_id
    :return: list
    """
    user_services = []
    wechat = await Wechat().filter(openid=openid).prefetch_related("user")
    if not wechat:
        return user_services

    for user in wechat:
        await user.fetch_related("service")
        user_services.append({
            "username": user.user.nickname,
            "is_admin": user.user.type,
            "u_id": user.user.u_id,
            "service_name": user.service.service_name,
            "s_id": user.service.s_id
        })

    return user_services


async def user_to_service(users: list):
    """
    # 查询用户所有服务商
    :param users:
    :return:
    """
    user_services = []
    for user in users:
        await user.fetch_related("service")
        user_services.append({
            "username": user.nickname,
            "is_admin": user.type,
            "u_id": user.u_id,
            "service_name": user.service.service_name,
            "s_id": user.service.s_id
        })

    return user_services


async def my_services(req: Request, web_code: str):
    """
    获取用户的服务商
    :param req:
    :param web_code: 请求码
    :return:
    """
    services = await req.app.state.cache.get(web_code+'-myService')
    if not services:
        return fail(code=2001, msg="登陆超时！")

    return success(data=json.loads(services), msg="当前用户服务商列表")
